/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  							 abstract_script_action.cpp

	$Header: /heroes4/abstract_script_action.cpp $

	$NoKeywords: $

 ************************************************************************/
// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "abstract_script_action.h"

#include <algorithm>
#include <cassert>
#include <string>

#include "sized_int_types.h"
#include "streambuf_operators.h"
#include "hero.h"
#include "army.h"

// --------------------------------------------------------------------------
// Unnamed namespace
// --------------------------------------------------------------------------

namespace
{

	// --------------------------------------------------------------------------
	// --------------------------------------------------------------------------
	typedef t_abstract_script_action::t_factory t_factory;

	// --------------------------------------------------------------------------
	// --------------------------------------------------------------------------
	t_factory const * g_factory_ptr_table[ k_script_action_type_count ];

} // Unnamed namespace

// --------------------------------------------------------------------------
// t_abstract_script_action 
// --------------------------------------------------------------------------

bool	t_abstract_script_action::m_removal_flag = false;

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
t_abstract_script_action_ptr
t_abstract_script_action::reconstruct_from_map(
	std::streambuf &	stream )
{
	int format_version = get< t_uint16 >( stream );
	return reconstruct_from_map( stream, format_version );
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
t_abstract_script_action_ptr
t_abstract_script_action::reconstruct_from_map(
	std::streambuf &	stream,
	int					format_version )
{
	t_abstract_script_action_ptr action_ptr = construct( stream );
	
	if ( !action_ptr->read_from_map( stream, format_version ) )
		return NULL;

	return action_ptr;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
t_abstract_script_action_ptr
t_abstract_script_action::reconstruct( std::streambuf &	stream, int version )
{
	t_abstract_script_action_ptr action_ptr = construct( stream );

	if ( !action_ptr || !action_ptr->read( stream, version ) )
		return NULL;

	return action_ptr;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
t_abstract_script_action_ptr
t_abstract_script_action::construct( std::streambuf &	stream )
{
	std::string type_keyword;
	if ( !read_string16( stream, type_keyword ) )
		return NULL;

	t_script_action_type type = get_script_action_type( type_keyword );
	if ( type < 0 || type >= k_script_action_type_count )
		return NULL;

	assert(
			std::find(
				&g_factory_ptr_table[ 0 ],
				&g_factory_ptr_table[ k_script_action_type_count ],
				static_cast< t_factory const * >( 0 ) )
		==	&g_factory_ptr_table[ k_script_action_type_count ] );

	return g_factory_ptr_table[ type ]->create();
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_abstract_script_action::read( std::streambuf& stream, int version )
{
	return true;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_abstract_script_action::write( std::streambuf& stream ) const
{
	return write_string16( stream, get_keyword( get_type() ) );
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
void t_abstract_script_action::flag_for_removal()
{
	m_removal_flag = true;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
void t_abstract_script_action::clear_removal()
{
	m_removal_flag = false;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_abstract_script_action::pending_removal()
{
	return m_removal_flag;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
int t_abstract_script_action::get_version()
{
	return 6;
}

// --------------------------------------------------------------------------
// t_abstract_script_action::t_factory members
// --------------------------------------------------------------------------

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
t_abstract_script_action::t_factory::t_factory( t_type type )
{
	assert( type >= 0 && type < k_script_action_type_count );
	assert( g_factory_ptr_table[ type ] == 0 );

	g_factory_ptr_table[ type ] = this;
}

